<template>
    <div :class="[
        bem.b(),
        bem.is('success', validateState == 'success'),
        bem.is('error', validateState === 'error')
    ]">
        <label :class="bem.e('label')">
            <slot name="label"></slot>
            {{ label }}
        </label>
        <div :class="bem.e('content')">
           <slot></slot>
           <div :class="bem.e('error')">
            <slot name="error">
            {{ validateMessage }}
            </slot>
           </div> 
        </div>
    </div>
</template>
<script lang="ts" setup>
import { ref,inject,computed,provide,onMounted } from 'vue';
import { createNamespace } from './createbem';
import { Arrayable, FormItemRule, FormItemValidateState } from './form-item';
import { formItemProps, FormItemContext } from './form-item';
import { FormContextKey } from './form';
import AsyncValdaitor, { Values } from 'async-validator'
const bem = createNamespace('form-item');
const validateState = ref<FormItemValidateState>('') // success  s
const validateMessage = ref('');

const formContext = inject(FormContextKey);
// 值
const props = defineProps(formItemProps)
defineOptions({
    name: 'z-form-item'
})
const converArray = (
  rules: Arrayable<FormItemRule> | undefined
): FormItemRule[] => {
  return rules ? (Array.isArray(rules) ? rules : [rules]) : []
}

// 规则
const _rules = computed(() => {
  const myRules = converArray(props.rules) // 自己的规则
  const formRules = formContext?.rules
  if (formRules && props.prop) {
    const _temp = formRules[props.prop]
    if (_temp) {
      myRules.push(...converArray(_temp))
    }
  }
  return myRules
})

// 过滤效验事件

const getRuleFiltered = (trigger: string) => {
  // blur change  ''
  const rules = _rules.value
 
  return rules.filter(rule => {  
    if (!rule.trigger || !trigger) return true // 这种情况意味着无论如何都要校验
    if (Array.isArray(rule.trigger)) { 
      return rule.trigger.includes(trigger)
    } else { 
      return rule.trigger === trigger
    }
  })
}
// 成功
const onValidationSuccesseded = () => {
  validateState.value = 'success'
  validateMessage.value = ''
}
// 失败
const onValidationFailed = (err: Values) => {
  validateState.value = 'error'
  const { errors } = err
  validateMessage.value = errors ? errors[0].message : ''
}
// 效验
const validate: FormItemContext['validate'] = async (trigger, callback?) => {
  // 拿到触发的时机，校验是否通过可以调用callback 或者调用promise.then方法
  const rules = getRuleFiltered(trigger); 
  // rules 就是触发的规则 , trigger就是触发的方式
  // 需要找到对应的数据源头 上面找到对应的prop

  // 触发事件了 ，找到对应的规则，和数据源在哪里，校验那个属性
  const modelName = props.prop
  // 拿到校验器
  const validator = new AsyncValdaitor({
    [modelName]: rules
  })
  const model = formContext?.model! 
  return validator
    .validate({
      [modelName]: model[modelName]
    })
    .then(() => {
      onValidationSuccesseded()
    })
    .catch((err: Values) => {
      onValidationFailed(err)
      return Promise.reject(err)
    })
}
const context: FormItemContext = {
  ...props,
  validate
} 

provide('form-item', context)

onMounted(() => {
  formContext?.addField(context) // 我将自己的上下文传递给了父亲
})
</script>